// store 的购物车 cart 模块的定义（代码引用的模块名:m_cart）

export default {
  // 要使用 store 的模块化开发，要开启命名空间
  namespaced: true,  
  // cart 模块的共享数据
  // state: { cart: [] } 这样定义共享状态数据也是可以的，用箭头函数的话，前后 {} 要用括号()包起来，
  // 返回的是 {cart: []}对象，否则会认为{}是函数定界符，会报错，而不认为是对象定义符，如下：
  state: () => ({
    // 定义购物车的数组：用于存储购物车中每个商品的信息
    // 购物车的数组，用来存储购物车中每个商品的信息对象
    // 每个商品的信息对象，都包含如下 6 个属性：
    // { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }
    cart: JSON.parse(uni.getStorageSync('cart') || '[]')  // 从本地存储读取
  }),
  // cart 模块的 actions方法(dispatch)：用于业务逻辑处理或请求后端的处理
  actions: {
    // actions里定义的方法自带的第一个参数为mini版store，只有 dispatch,commit,state,getters 常用属性和方法
    addToCart(store, goods) {
      // 这里是在 cart 模块直接查找state的cart，不用像在vue组件中加多一个m_cart模块名：this.$store.state.m_cart.cart
      // 数据的 find 方法：只返回满足条件 x.goods_id === goods_id 的元素，找不到返回 undefined
      const findResults = store.state.cart.find(x => x.goods_id === goods.goods_id)
      if(!findResults) {  // 如果找不到，即商品不存在购物车中，直接加入购物车
        store.state.cart.push(goods)
        // 修改购物车的商品数量后，需调用函数持久化到本地存储
        // this.commit('m_cart/saveCartToStorage')  // this方式调用，要加模块名 m_cart
        store.commit('saveCartToStorage')
      } else {  // 如果找到存在购物里，调用 mutations 的 editGoodsCount 方法将商品数量加1即可
        store.commit('editGoodsCount', findResults)  // findResults是 state.cart 的引用地址，直接修改 findResults 即可
      }
      // console.log(findResults)
    }
  },
  // cart 模块的 mutations方法(commit)：用于直接操作或加工数据
  mutations: {
    // 如果找到存在购物里，调用 mutations 的 editGoodsCount 方法将商品数量加1即可
    editGoodsCount(state, goods) {
      goods.goods_count++
      // 修改购物车的商品数量后，需调用函数持久化到本地存储
      this.commit('m_cart/saveCartToStorage')  // 在 mutations 的方法调用另一个 mutations 的方式，用 this.commit 即可
    },
    // 购物车商品信息持久化到本地存储
    saveCartToStorage(state) {
      uni.setStorageSync('cart', JSON.stringify(state.cart))
    },
    // 更改购物车商品是否选中的状态
    updateGoodsState(state, goods) {
      const findResultes = state.cart.find(x => x.goods_id === goods.goods_id)
      if(findResultes) {
        // 修改商品是否选中的状态
        findResultes.goods_state = goods.goods_state
        // 修改购物车的商品状态后，需调用函数持久化到本地存储
        this.commit('m_cart/saveCartToStorage')
      }
    },
    // 修改购物车中商品的数量，并持久化到本地保存
    updateGoodsCount(state, goods) {
      const findResults = state.cart.find(x => x.goods_id === goods.goods_id)
      if(findResults) {
        findResults.goods_count = goods.goods_count
        // 修改购物车的商品数量后，需调用函数持久化到本地存储
        this.commit('m_cart/saveCartToStorage')
      }
    },
    // 删除购物车中商品，并持久化到本地保存
    removeGoodsById(state, goods) {
      // 方法一：用 filter 反向过淲，只保留不被删除的数组元素（filter方法不会修改原数组，必须重新赋值原数组）
      state.cart = state.cart.filter(x => x.goods_id !== goods.goods_id)
      
      // 方法二：用 for/forEach 循环和 Array.splice 方法实现
      // state.cart.forEach((item, index, arr) => {
      //   if(item.goods_id === goods.goods_id) {
      //     // array.splice在原数组删除：参数index，表示删除指定索引号的元素，1表示如有重复的，只会删除一个
      //     state.cart.splice(index, 1)
      //   }
      // })
      
      // 删除购物车的商品后，需调用函数持久化到本地存储
      this.commit('m_cart/saveCartToStorage')
    },
    // 根据全选按钮是否选中，更改购物车所有商品是否选中
    updateAllGoodsState(state, newState) {
      state.cart.map(x => x.goods_state = newState)
      // 更改商品状态后，需调用函数持久化到本地存储
      this.commit('m_cart/saveCartToStorage')
    }
  },
  // cart 模块的 getters
  getters: {
    // 购物车所有商品的总件数（包含不选中）
    goodsTotal(state) {  // getters 定义的类似 computed 中的计算属性函数参数只有一个 state 参数
      let cnt = 0
      state.cart.forEach(x => cnt += x.goods_count)
      return cnt
    },
    // 购物车所有勾选商品的总件数
    checkedCount(state) {
      // 方法一：用循环
      // let cnt = 0
      // state.cart.forEach((item, index, arr) => {
      //   if(item.goods_state) cnt += item.goods_count
      // })
      // return cnt
      
      // 方法二：用数组的filter和reduce方法
      return state.cart.filter(x => x.goods_state).reduce((cnt, item) => cnt+=item.goods_count, 0) 
    },
    // 购物车合计总价格计算属性
    payAmount(state) {
      return state.cart.filter(x => x.goods_state).reduce((sum, item) => sum += item.goods_price * item.goods_count, 0)
    }
  }
}